<script setup lang="ts">
import { onMounted, onUnmounted, watch, computed, ref, getCurrentInstance } from 'vue'
import { useThemeStore } from '@/store/theme';
import { userStore } from '@/store/user';
import { init, dispose } from 'klinecharts'
import { registerIndicatorMa1, registerIndicatorEma } from '@/hooks/index'
import { query } from '@/apis/currency'
import { useCoinStore } from '@/store/coin'
import { kanbanStore } from '@/store/user';
import { formatNumberWithThousands } from '@/utils/utils';
import { ElDropdown } from 'element-plus';
import coinInfo from './coinInfo.vue';
import 'element-plus/es/components/dropdown/style/css';
import TootipOrdinary from './kline/TootipOrdinary1.vue';
import TootipMA from './kline/TootipMA1.vue';
import TootipEMA from './kline/TootipEMA.vue';
const isLoading = ref<boolean>(true)
const dropdownRef = ref()
const instance = getCurrentInstance()
let currencySocket: any
const currencyId = ref<string>()
const scrollContainer = ref<HTMLElement>()
const props = defineProps(['info', 'coinInfo.coin', 'id', 'coinInfo', 'type', 'index', 'coinList'])
const weekList = ref([
  { title: '1分钟', value: 1, type: 'MINUTE' },
  { title: '5分钟', value: 5, type: 'MINUTE' },
  { title: '15分钟', value: 15, type: 'MINUTE' },
  { title: '1小时', value: 1, type: 'HOUR' },
  { title: '1天', value: 1, type: 'DAY' },
  // { title: '1周', value: 1, type: 'WEEK' },
])
interface CurrencyInfo {
  open: number;
  close: number;
  high: number;
  low: number;
  volume: number;
  time: string;
}

const currentInfo = ref<CurrencyInfo>({
  open: 0,
  close: 0,
  high: 0,
  low: 0,
  volume: 0,
  time: ''
})
const indicatorData = ref({})
const style = ref({})
const isContentOverflowValue = ref(false)
interface KlineItem {
  open: number;
  close: number;
  openTime: number;
  closeTime: number;
  lowest: number;
  highest: number;
  total: number;
  date: Date;
  timestamp: number;
};

const obj = computed(() => {
  let info = {} as any
  useCoinStore().coinPriceList.forEach(item => {
    info[item.coinName] = item
  })
  return info
}) as any

const info = computed(() => {
  return props.coinList?.find((item: any) => item.currencyPair === props.coinInfo.coin + '-USDT')
})
const formatTimestampToDateTime = (timestamp: number, fallback = '暂无时间') => {
  // 1. 处理时间戳（兼容秒级/毫秒级，判断长度：10位是秒级，13位是毫秒级）
  let time = Number(timestamp);
  if (isNaN(time)) return fallback; // 非数字直接返回默认值

  // 秒级时间戳转毫秒级（10位 → 13位）
  if (time.toString().length === 10) {
    time *= 1000;
  }

  // 2. 创建 Date 对象并验证有效性
  const date = new Date(time);
  if (date.toString() === 'Invalid Date') return fallback; // 无效时间返回默认值

  // 3. 提取年/月/日/时/分（补零处理，确保格式为两位数）
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始，需 +1
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');

  // 4. 拼接成目标格式
  return `${year}/${month}/${day} ${hours}:${minutes}`;
};
const connectCurrency = () => {
  const item = weekList.value.find(item => item.title === props.coinInfo.kLineType)
  const info = item ? item.value + item.type : '15MINUTE'
  if (currencyId.value) {
    currencySocket.unsubscribe(currencyId.value, `/topic/marketk/${props.coinInfo.coin}-USDT/${info}`)
  }
  currencyId.value = Date.now().toString(36) + Math.floor(Math.random() * 1000).toString(36)
  currencySocket.subscribe(currencyId.value, `/topic/marketk/${props.coinInfo.coin}-USDT/${info}`, (data: KlineItem) => {
    isLoading.value = false
    chart?.updateData({
      close: data.close,
      high: data.highest,
      low: data.lowest,
      open: data.open,
      timestamp: data.timestamp,
      volume: data.total
    })
    kanbanStore().setCoinPriceInfo(props.type, props.index, {
      close: data.close + '',
      high: data.highest + '',
      low: data.lowest + '',
      open: data.open + '',
      time: formatTimestampToDateTime(data.timestamp),
      volume: data.total + ''
    })
  })
}
let chart: any = null
const queryFn = async () => {
  const item = weekList.value.find(item => item.title === props.coinInfo.kLineType)
  const data = await query({
    currencyPair: props.coinInfo.coin + '-USDT',
    timeType: item?.type || 'MINUTE',
    timeNumber: item?.value || 15,
    start: '0',
    stop: '1000'
  })

  return data
}
const changeWeek = async (type: string) => {
  isLoading.value = true
  kanbanStore().setCoinKlineType(props.type, props.index, type)
  connectCurrency()
  const data = await queryFn()
  const list = data.map(item => {
    return {
      close: item.close,
      high: item.highest,
      low: item.lowest,
      open: item.open,
      timestamp: item.timestamp,
      volume: item.total
    }
  })
  chart?.applyNewData(list)
}
const isContentOverflow = () => {
  if (!scrollContainer.value) return false;
  const container = scrollContainer.value;
  const containerWidth = container.clientWidth;
  const children = container.children as unknown as HTMLElement[];
  let totalChildrenWidth = 0;
  for (let i = 0; i < children.length; i++) {
    totalChildrenWidth += children[i].offsetWidth;
  }
  totalChildrenWidth += (children.length - 1) * 10;
  isContentOverflowValue.value = totalChildrenWidth > containerWidth;
};
const width = ref('')

onMounted(async () => {
  useCoinStore().setInCharts(false)
  const data = await queryFn()
  const list = data.map(item => {
    return {
      close: item.close,
      high: item.highest,
      low: item.lowest,
      open: item.open,
      timestamp: item.timestamp,
      volume: item.total
    }
  })
  chart = init(props.id, {
    styles: {
      // 蜡烛图
      candle: {
        bar: {
          upColor: '#2dbd85',
          downColor: '#f6475d',
          noChangeColor: '#2dbd85',
          upBorderColor: '#2dbd85',
          downBorderColor: '#f6475d',
          noChangeBorderColor: '#2dbd85',
          upWickColor: '#2DC08E',
          downWickColor: '#F92855',
          noChangeWickColor: '#2dbd85'
        },
        // 面积图
        area: {
          lineSize: 2,
          lineColor: '#2196F3',
          value: 'close',
          smooth: false,
          backgroundColor: [{
            offset: 0,
            color: 'rgba(33, 150, 243, 0.01)'
          }, {
            offset: 1,
            color: 'rgba(33, 150, 243, 0.2)'
          }],
          point: {
            show: true,
            radius: 4,
            rippleRadius: 8,
            animation: true,
            animationDuration: 1000
          }
        },
        priceMark: {
          high: {
            textOffset: 5,
          }
        },
        tooltip: {
          offsetTop: 0,
          offsetLeft: -8,
        }
      },
      indicator: {

        bars: [
          {
            borderSize: 1,
            borderDashedValue: [2, 2],
            upColor: '#2dbd85',
            downColor: '#f6475d',
            noChangeColor: '#888888'
          }
        ]
      },
      grid: {
        horizontal: {
          color: useThemeStore().theme === 'dark' ? '#22282f' : '#ededed',
        },
        vertical: {
          color: useThemeStore().theme === 'dark' ? '#22282f' : '#ededed',
        },
      },
      yAxis: {
        tickLine: {
          show: false,
        },
        axisLine: {
          size: 1,
          color: useThemeStore().theme === 'dark' ? '#333b47' : '#ededed',
        },
      },
      separator: {
        color: useThemeStore().theme === 'dark' ? '#333b47' : '#ededed',
      },
      xAxis: {
        tickLine: {
          show: false,
        },
        axisLine: {
          color: useThemeStore().theme === 'dark' ? '#333b47' : '#ededed',
        },
      },
      crosshair: {
        horizontal: {
          text: {
            color: useThemeStore().theme === 'dark' ? '#fff' : '#000',
            backgroundColor: useThemeStore().theme === 'dark' ? '#434c5a' : '#dddddd'
          }
        },
        vertical: {
          text: {
            color: useThemeStore().theme === 'dark' ? '#fff' : '#000',
            backgroundColor: useThemeStore().theme === 'dark' ? '#434c5a' : '#dddddd'
          }
        }
      }
    },
  })
  chart.setStyles({
    candle: {
      tooltip: {
        showRule: 'none'
      }
    },
    indicator: {
      tooltip: {
        showRule: 'none'
      }
    }
  })
  chart.setBarSpace(6)
  chart.applyNewData(list)
  chart.setPriceVolumePrecision(useCoinStore().getPrice(props.coinInfo.coin)?.unitDecimals, 2)
  chart.setLeftMinVisibleBarCount(9)
  chart.setOffsetRightDistance(54)
  registerIndicatorMa1(props.type, props.index)
  // registerIndicatorEma()
  chart.subscribeAction('onCrosshairChange', (e: any) => {
    const data = e.kLineData
    indicatorData.value = e.indicatorData
    kanbanStore().setInCharts(props.type, props.index, true)
    data.time = formatTimestampToDateTime(data.timestamp)
    currentInfo.value = data
  })
  chart.setLocale('zh-CN')
  if ((kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.checked) {
    chart.createIndicator({
      name: 'MA',
      visible: (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.hide,
    }, true, { id: 'candle_pane' })
  }
  // if (userStore().mainIndicator.ema.checked) {
  //   chart.createIndicator({
  //     name: 'EMA',
  //     visible: userStore().mainIndicator.ema.hide,
  //   }, true, { id: 'candle_pane' })
  // }
  width.value = (chart?.getSize('candle_pane', 'main')?.width - 14) + 'px'
  setTimeout(() => {
    isContentOverflow()
  }, 0);
})
watch(() => userStore().currencySocket, async (val) => {
  if (val) {
    const data = await queryFn()
    const list = data.map(item => {
      return {
        close: item.close,
        high: item.highest,
        low: item.lowest,
        open: item.open,
        timestamp: item.timestamp,
        volume: item.total
      }
    })
    chart?.applyNewData(list)
    if (instance) {
      currencySocket = instance.appContext.config.globalProperties.$currencySocket
      if (currencySocket.connected) {
        connectCurrency()
      }
    }
  }
}, { immediate: true })
watch(() => (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.checked, (v, o) => {
  if (v) {
    registerIndicatorMa1(props.type, props.index)
    chart.removeIndicator('candle_pane', 'MA')
    chart.createIndicator({
      name: 'MA',
      visible: (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.hide,
    }, true, { id: 'candle_pane' })
  } else {
    chart.removeIndicator('candle_pane', 'MA')
  }
})
watch(() => (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.list, (v, o) => {
  if ((kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.checked) {
    registerIndicatorMa1(props.type, props.index)
    chart.removeIndicator('candle_pane', 'MA')
    chart.createIndicator({
      name: 'MA',
      visible: (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.hide,
    }, true, { id: 'candle_pane' })
  }
})
watch(() => (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.hide, (v, o) => {
  chart.removeIndicator('candle_pane', 'MA')
  chart.createIndicator({
    name: 'MA',
    visible: (kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.hide,
  }, true, { id: 'candle_pane' })
})
watch(() => userStore().mainIndicator.ema.checked, (v, o) => {
  if (v) {
    registerIndicatorEma()
    chart.removeIndicator('candle_pane', 'EMA')
    chart.createIndicator({
      name: 'EMA',
      visible: userStore().mainIndicator.ema.hide,
    }, true, { id: 'candle_pane' })
  } else {
    chart.removeIndicator('candle_pane', 'EMA')
  }
})
watch(() => userStore().mainIndicator.ema.list, (v, o) => {
  if (userStore().mainIndicator.ema.checked) {
    registerIndicatorEma()
    chart.removeIndicator('candle_pane', 'EMA')
    chart.createIndicator({
      name: 'EMA',
      visible: userStore().mainIndicator.ema.hide,
    }, true, { id: 'candle_pane' })
  }
})
watch(() => userStore().mainIndicator.ema.hide, (v, o) => {
  chart.removeIndicator('candle_pane', 'EMA')
  setTimeout(() => {
    chart.createIndicator({
      name: 'EMA',
      visible: userStore().mainIndicator.ema.hide,
    }, true, { id: 'candle_pane' })
  }, 100);
})
watch(() => props.info, (v) => {
  style.value = {
    width: v.width - 32 + 'px',
    height: v.height - 55 - 41 - 6 + 'px'
  }
  setTimeout(() => {
    chart?.resize()
  }, 100);
  setTimeout(() => {
    width.value = (chart?.getSize('candle_pane', 'main').width - 14) + 'px'
  }, 200);
}, {
  deep: true, // 若为对象/数组需开启深度监听
  immediate: true // 关键：立即执行一次
})
watch(() => props.coinInfo.coin, async (v) => {
  isLoading.value = true
  connectCurrency()
  const data = await queryFn()
  const list = data.map(item => {
    return {
      close: item.close,
      high: item.highest,
      low: item.lowest,
      open: item.open,
      timestamp: item.timestamp,
      volume: item.total
    }
  })
  chart.setPriceVolumePrecision(useCoinStore().getPrice(props.coinInfo.coin)?.unitDecimals, 2)
  chart?.applyNewData(list)
})

watch(() => useThemeStore().theme, (v) => {
  chart?.setStyles({
    grid: {
      horizontal: {
        color: v === 'dark' ? '#22282f' : '#ededed',
      },
      vertical: {
        color: v === 'dark' ? '#22282f' : '#ededed',
      },
    },
    yAxis: {
      axisLine: {
        size: 1,
        color: v === 'dark' ? '#333b47' : '#ededed',
      },
    },
    separator: {
      color: v === 'dark' ? '#333b47' : '#ededed',
    },
    xAxis: {
      axisLine: {
        color: v === 'dark' ? '#333b47' : '#ededed',
      },
    },
    crosshair: {
      horizontal: {
        text: {
          color: v === 'dark' ? '#fff' : '#000',
          backgroundColor: v === 'dark' ? '#434c5a' : '#dddddd'
        }
      },
      vertical: {
        text: {
          color: v === 'dark' ? '#fff' : '#000',
          backgroundColor: v === 'dark' ? '#434c5a' : '#dddddd'
        }
      }
    }
  })
})



const mouseenterFn = () => {
  kanbanStore().setInCharts(props.type, props.index, false)
}

const emit = defineEmits(['showindicator', 'changeCoin'])
const showindicator = (e: string) => {
  emit('showindicator', e)
}

const changeCoin = (e: string) => {
  emit('changeCoin', e)
  if (dropdownRef.value) {
    dropdownRef.value.handleClose(); // 调用关闭方法
  }
}

const mouseEnter = () => {
  kanbanStore().setInCharts(props.type, props.index, false)
}
const mouseLeave = () => {
  kanbanStore().setInCharts(props.type, props.index, false)
}
onUnmounted(() => {
  const item = weekList.value.find(item => item.title === props.coinInfo.kLineType)
  const info = item ? item.value + item.type : '15MINUTE'
  if (currencySocket) {
    currencySocket.unsubscribe(currencyId.value, `/topic/marketk/${props.coinInfo.coin}-USDT/${info}`)
  }
  dispose(props.id)
})

</script>

<template>
  <div>
    <div class="h-[55px] w-full pl-[12px] box-border flex items-center">
      <ElDropdown ref="dropdownRef" trigger="click" :show-arrow="false" placement="bottom-start">
        <div class="font-bold cursor-pointer">{{ props.coinInfo.coin }}/USDT <span
            class="iconfont icon-xiangxia text-[8px] ml-[6px]"></span> </div>
        <template #dropdown>
          <div class="w-[320px]">
            <coinInfo @changeCoin="changeCoin" />
          </div>
        </template>
      </ElDropdown>
      <div class="ml-[20px]">
        <div class="text-[14px]" :class="[info ? (info.percent >= 0 ? 'text-rise' : 'text-fall') : '']">{{ info ?
          (obj[(info.currencyPair.split('-')[0])]?.unitDecimals
            ?
            formatNumberWithThousands(info?.amount.toFixed(obj[(info.currencyPair.split('-')[0])].unitDecimals))
            : formatNumberWithThousands(info?.amount)) : '-' }}</div>
        <div class="text-[12px]">${{ info ? (obj[(info.currencyPair.split('-')[0])]?.unitDecimals
          ?
          formatNumberWithThousands(info?.externalPrice.toFixed(obj[(info.currencyPair.split('-')[0])].unitDecimals))
          : formatNumberWithThousands(info?.externalPrice)) : '-' }}</div>
      </div>
      <div class="ml-[20px]">
        <div class="text-[12px]">24h涨跌</div>
        <div class="text-[12px]" :class="[info ? (info.percent >= 0 ? 'text-rise' : 'text-fall') : '']">{{ info ?
          (info.percent
            >= 0 ? '+' : '') + Number(info.percent *
              100).toFixed(2)
          + '%'
          : '-'
        }}</div>
      </div>
      <div class="ml-[20px]">
        <div class="text-[12px]">24h最高价</div>
        <div class="text-[12px]">{{ info ?
          (obj[(info.currencyPair.split('-')[0])]?.unitDecimals
            ?
            formatNumberWithThousands(info?.highest.toFixed(obj[(info.currencyPair.split('-')[0])].unitDecimals))
            : formatNumberWithThousands(info?.highest)) : '-' }}</div>
      </div>
      <div class="ml-[20px]">
        <div class="text-[12px]">24h最低价</div>
        <div class="text-[12px]">{{ info ?
          (obj[(info.currencyPair.split('-')[0])]?.unitDecimals
            ?
            formatNumberWithThousands(info?.lowest.toFixed(obj[(info.currencyPair.split('-')[0])].unitDecimals))
            : formatNumberWithThousands(info?.lowest)) : '-' }}</div>
      </div>
      <div class="ml-[20px]">
        <div class="text-[12px]">24h成交量({{ info?.currencyPair.split('-')[0] }})</div>
        <div class="text-[12px]">{{ info ?
          (obj[(info.currencyPair.split('-')[0])]?.coinDecimals
            ?
            formatNumberWithThousands(info?.total.toFixed(obj[(info.currencyPair.split('-')[0])].coinDecimals))
            : formatNumberWithThousands(info?.total)) : '-' }}</div>
      </div>
    </div>
    <div
      class="h-[20px] pl-[16px]  py-[10px] text-[12px] flex items-center text-gray-400 dark:text-[#707A8A] border-solid border-0 border-b-[1px] border-[#eaecef] dark:border-[#22282f]">
      <div class="w-[400px] cursor-pointer overflow-hidden flex flex-nowrap gap-[10px] items-center h-[20px]"
        ref="scrollContainer">
        <div class="flex-shrink-0" v-show="isContentOverflowValue"></div>
        <div @click="changeWeek(item.title)"
          :class="[item.title === props.coinInfo.kLineType ? 'text-black dark:text-[#eaecef]' : '']"
          v-for="item, i in weekList" :key="i" class=" flex-shrink-0 ">{{ item.title }}</div>
        <div class="iconfont icon-jishuzhibiao" @click="showindicator('')"></div>
        <div class="iconfont icon-shezhi"></div>
      </div>
    </div>
    <div :id="id" :style="style" class="relative" @mouseenter="mouseEnter" @mouseleave="mouseLeave">
      <div
        class=" absolute left-0 top-0 flex dark:text-[#202228] items-center justify-center text-[60px] font-bold text-[#f6f6f7]"
        :style="style">UHX</div>
      <div class=" absolute left-[2px] top-[5px] text-[12px] z-[20]" @mouseenter="mouseenterFn">
        <TootipOrdinary :currentInfo="currentInfo" :width="width" :type="type" :index="index" />
        <TootipMA :type="type" :index="index" @setMainIndicator="showindicator"
          v-if="(kanbanStore()[props.type as keyof ReturnType<typeof kanbanStore>] as any[])[props.index].mainIndicator.ma.checked"
          :currentInfo="indicatorData" :width="width" />
        <!-- <TootipEMA @setMainIndicator="showindicator"
          v-if="!userStore().mainIndicator.ema.hiden && userStore().mainIndicator.ema.checked"
          :currentInfo="indicatorData" :width="width" /> -->
      </div>
      <div v-show="isLoading" :style="style"
        class="flex left-0 top-0 justify-center items-center absolute z-[10] bg-[#ffffff] dark:bg-[#181a21]">
        <Loading />
      </div>
    </div>

  </div>
</template>